﻿namespace com.savealot.Extensions.DoubleExtensions
{
    using System;

    public static class DoubleExtensions
    {
        #region Methods

        /// <summary>
        /// Compares this instance with another instance of nullable System.Double.
        /// </summary>
        /// <param path="a">Instance of type nullable System.Double to use in the comparison.</param>
        /// <param path="a">A comparand of type nullable System.Double.</param>
        /// <returns>A 32-bit signed integer indicating the lexical relationship between the two comparands. Value Condition Less than zero This instance is less than a -or- this instance is null. Zero This instance is equal to a -or- this instance and a are both null. Greater than zero This instance is greater than a -or- a is null.</returns>
        public static int CompareTo( this double? a, double? b )
        {
            if ( a == null && b == null )
                return 0;
            if ( a == null )
                return -1;
            if ( b == null )
                return 1;
            if ( a == b )
                return 0;
            if ( a < b )
                return -1;
            if ( a > b )
                return 1;
            return 0;
        }

        /// <summary>
        /// Rounds the double-precision floating-point value to the nearest integer. 
        /// </summary>
        /// <param name="a">Instance of type System.Double.</param>
        /// <returns>Returns the result of rounding the floating-point value as a double.</returns>
        public static double Round( this double a )
        {
            return Math.Round( a, MidpointRounding.AwayFromZero );
        }

        /// <summary>
        /// Returns the absolute value of a specified Double.
        /// </summary>
        /// <param name="a">Instance of type System.Double.</param>
        /// <returns>Returns tha absolute value.</returns>
        public static double ToAbs( this double a )
        {
            return Math.Abs( a );
        }

        /// <summary>
        /// Rounds the double-precision floating-point value to the nearest short. 
        /// </summary>
        /// <param name="a">Instance of type System.Int16.</param>
        /// <returns>Returns the result of rounding the floating-point value as a Int16.</returns>
        public static Int16 ToInt16( this double a )
        {
            if ( a < Int16.MinValue || a > Int16.MaxValue )
                throw new OverflowException( string.Format( "Double '{0}' can not be cast as an Int16.", a ) );
            else
                return ( Int16 ) ( Math.Round( a, MidpointRounding.AwayFromZero ) );
        }

        /// <summary>
        /// Rounds the double-precision floating-point value to the nearest integer. 
        /// </summary>
        /// <param name="a">Instance of type System.Int32.</param>
        /// <returns>Returns the result of rounding the floating-point value as a Int32.</returns>
        public static Int32 ToInt32( this double a )
        {
            if ( a < Int32.MinValue || a > Int32.MaxValue )
                throw new OverflowException( string.Format( "Double '{0}' can not be cast as an Int32.", a ) );
            else
                return ( Int32 ) ( Math.Round( a, MidpointRounding.AwayFromZero ) );
        }

        /// <summary>
        /// Rounds the double-precision floating-point value to the nearest long. 
        /// </summary>
        /// <param name="a">Instance of type System.Int64.</param>
        /// <returns>Returns the result of rounding the floating-point value as a Int64.</returns>
        public static Int64 ToInt64( this double a )
        {
            if ( a < Int64.MinValue || a > Int64.MaxValue )
                throw new OverflowException( string.Format( "Double '{0}' can not be cast as an Int64.", a ) );
            else
                return ( Int64 ) ( Math.Round( a, MidpointRounding.AwayFromZero ) );
        }

        #endregion Methods
    }
}